package com.jiashn.minio.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.jiashn.minio.domain.OpuSysFiles;
import com.jiashn.minio.mapper.OpuSysFilesMapper;
import com.jiashn.minio.service.OpuSysFilesService;
import com.jiashn.minio.utils.JsonResult;
import com.jiashn.minio.utils.MinioBucketEnum;
import com.jiashn.minio.utils.MinioHelper;
import com.jiashn.minio.utils.MinioPearUploadUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.Objects;

/**
 * @author: jiangjs
 * @description:
 * @date: 2023/10/20 15:19
 **/
@Service
@AllArgsConstructor(onConstructor = @__(@Autowired))
@Slf4j
public class OpuSysFilesServiceImpl implements OpuSysFilesService {

    private final OpuSysFilesMapper opuSysFilesMapper;
    private final MinioPearUploadUtil minioPearUploadUtil;

    @Override
    public Boolean isExistFile(String md5Code, String bucketName) {
        Long count = opuSysFilesMapper.selectCount(Wrappers.<OpuSysFiles>lambdaQuery()
                .eq(OpuSysFiles::getMd5Code, md5Code)
                .eq(OpuSysFiles::getBucketName, bucketName));
        return count > 0;
    }

    @Override
    public JsonResult<String> uploadSingleFile(MultipartFile file, MinioBucketEnum bucketEnum) {
        try (InputStream ism = file.getInputStream()){
            String md5Str = DigestUtils.md5DigestAsHex(ism);
            Boolean existFile = this.isExistFile(md5Str, bucketEnum.getBucket());
            if (!existFile){
                String fileName = md5Str + "_" + file.getOriginalFilename();
                Boolean uploadFlag = minioPearUploadUtil.upLoadInputStream(ism, bucketEnum.getBucket(),fileName);
                if (uploadFlag){
                    OpuSysFiles sysFiles = new OpuSysFiles();
                    String suffix = StringUtils.isNoneBlank(fileName) ? fileName.substring(fileName.indexOf(".")+1) : "" ;
                    sysFiles.setFileName(fileName)
                            .setBucketName(bucketEnum.getBucket())
                            .setMd5Code(md5Str).setSuffix(suffix);
                    opuSysFilesMapper.insert(sysFiles);
                }
            }
            return JsonResult.success(md5Str);
        } catch (Exception e) {
            log.error("单个文件上传报错："+e.getMessage());
            e.printStackTrace();
            return JsonResult.fails("上传文件失败");
        }
    }

    @Override
    public void downFile(String md5Code, MinioBucketEnum bucketEnum,HttpServletResponse response) {
        OpuSysFiles opuSysFiles = opuSysFilesMapper.selectOne(Wrappers.<OpuSysFiles>lambdaQuery()
                .eq(OpuSysFiles::getMd5Code, md5Code)
                .eq(OpuSysFiles::getBucketName, bucketEnum.getBucket()));
        String fileName = Objects.nonNull(opuSysFiles) ? opuSysFiles.getFileName() : "";
        try (InputStream ism = minioPearUploadUtil.downLoadFile(fileName, bucketEnum.getBucket())){
            String contentType = this.getFileContentType(opuSysFiles.getSuffix());
            response.setContentType(contentType);
            response.setHeader("Content-disposition", "inline; filename="+URLEncoder.encode(fileName, "UTF-8"));
            byte[] bytes = new byte[1024];
            OutputStream osm = response.getOutputStream();
            int count;
            while((count = ism.read(bytes)) !=-1){
                osm.write(bytes, 0, count);
            }
            osm.flush();
            osm.close();
        } catch (Exception e){
            log.error("下载文件报错："+e.getMessage());
            e.printStackTrace();
        }
    }

    private String getFileContentType(String suffix){
        switch (suffix){
            case "jpg":
            case "jpeg":
                return "image/jpeg";
            case "png":
                return "image/png";
            case "gif":
                return "image/gif";
            case "xml":
                return "application/xml";
            case "pdf":
                return "application/pdf";
            case "xls":
                return "application/vnd.ms-excel";
            case "xlsx":
                return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
            case "doc":
                return "application/msword";
            case "docx":
                return "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
            case "ppt":
                return "application/vnd.ms-powerpoint";
            case "pptx":
                return "application/vnd.openxmlformats-officedocument.presentationml.presentation";
            default:
                return "";
        }
    }


}
